<?php
/**
 * @author 	Vu Nhat Lam
 * 			Mail: lamvnd@gmail.com
 * 			Mobile: 0984 52 62 68
 * @version 1.0.0
 */
// ******************************************************************************
// For bttracker
function benc($obj)
{
	if (!is_array($obj) || !isset($obj['type']) || !isset($obj['value'])) return;
	$c = $obj['value'];
	switch ($obj['type'])
	{
		case 'dictionary':
			return benc_dict($c);
		case 'integer':
			return benc_int($c);
		case 'list':
			return benc_list($c);
		case 'string':
			return benc_str($c);
	}
}

function benc_dict($d)
{
	$s = 'd';
	$keys = array_keys($d);
	sort($keys);
	foreach ($keys as $k)
	{
		$v = $d[$k];
		$s .= benc_str($k);
		$s .= benc($v);
	}
	$s .= 'e';
	return $s;
}

function benc_int($i)
{
	return 'i' . $i . 'e';
}

function benc_list($a)
{
	$s = 'l';
	foreach ($a as $e)
	{
		$s .= benc($e);
	}
	$s .= 'e';
	return $s;
}

function benc_str($s)
{
	return strlen($s) . ':' . $s;
}

function benc_resp($d)
{
	benc_resp_raw(benc(array('type' => 'dictionary', 'value' => $d)));
}

function benc_resp_raw($msg)
{
	header('Content-Type: text/plain');
	header('Pragma: no-cache');
	header('Cache-Control: no-cache, must-revalidate');

	if (defined('NOSHUTDOWNFUNC'))
	{
		exec_shut_down();
	}

	echo $msg;

	flush();
	exit();
}

function errorexit($msg)
{
	benc_resp(array(
		'failure reason' => array(
			'type' => 'string',
			'value' => $msg
		)
	));
}

function hash_where($name, $hash)
{
	global $vbulletin;

	$shhash = str_replace(' ', '', $hash);
	if ($shhash == $hash)
	{
		return "$name = '" . $vbulletin->db->escape_string($hash) . "'";
	}
	else
	{
		return "($name = '" . $vbulletin->db->escape_string($hash) . "' OR $name = '" . $vbulletin->db->escape_string($shhash) . "')";
	}
}

// ******************************************************************************

// ******************************************************************************
// For btdownload
function bdec_file($f, $ms)
{
	$fp = fopen($f, 'rb');
	if (!$fp) return;
	$e = fread($fp, $ms);
	fclose($fp);
	return bdec($e);
}

function bdec($s)
{
	switch ($s[0])
	{
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			return bdec_str($s);
		case 'l':
			return bdec_list($s);
		case 'd':
			return bdec_dict($s);
		case 'i':
			return bdec_int($s);
	}
}

function bdec_dict($s)
{
	if ($s[0] != 'd') return;
	$sl = strlen($s);
	$i = 1;
	$v = array();
	$ss = 'd';
	for (;;)
	{
		if ($i >= $sl) return;
		if ($s[$i] == 'e') break;
		$ret = bdec(substr($s, $i));
		if (!isset($ret) || !is_array($ret) || $ret['type'] != 'string') return;
		$k = $ret['value'];
		$i += $ret['strlen'];
		$ss .= $ret['string'];
		if ($i >= $sl) return;
		$ret = bdec(substr($s, $i));
		if (!isset($ret) || !is_array($ret)) return;
		$v[$k] = $ret;
		$i += $ret['strlen'];
		$ss .= $ret['string'];
	}
	$ss .= 'e';
	return array(type => 'dictionary', value => $v, strlen => strlen($ss), string => $ss);
}

function bdec_int($s)  
{
      if ($s[0] != 'i') return;
      $v = intval(substr($s, 1, 16));
      if ($v === '-0') return;
      if ($v[0] == '0' && strlen($v) != 1) return;
      $full_v = substr($s, 1, strlen($v));
      $ss = 'i' . $full_v . 'e';
      return array(type => 'integer', value => $full_v, strlen => strlen($ss), string => $ss);
}

function bdec_list($s)
{
	if ($s[0] != 'l') return;
	$sl = strlen($s);
	$i = 1;
	$v = array();
	$ss = 'l';
	for (;;)
	{
		if ($i >= $sl) return;
		if ($s[$i] == 'e') break;
		$ret = bdec(substr($s, $i));
		if (!isset($ret) || !is_array($ret)) return;
		$v[] = $ret;
		$i += $ret['strlen'];
		$ss .= $ret['string'];
	}
	$ss .= 'e';
	return array(type => 'list', value => $v, strlen => strlen($ss), string => $ss);
}

function bdec_str($s)
{
	$l = intval($s);
	$pl = strlen($l) + 1;
	$v = substr($s, $pl, $l);
	$ss = substr($s, 0, $pl + $l);
	if (strlen($v) != $l) return;
	return array(type => 'string', value => $v, strlen => strlen($ss), string => $ss);
}
// ******************************************************************************

// ******************************************************************************
// For btview
function get_ratio($uploaded, $downloaded)
{
	if ($downloaded > 0)
	{
		$ratio = number_format($uploaded / $downloaded, 3);
	}
	elseif ($uploaded > 0)
	{
		$ratio = 'Inf.';
	}
	else
	{
		$ratio = '---';
	}
	return $ratio;
}

function get_ratio_color($ratio)
{
	if ($ratio < 0.1) return "#ff0000";
	if ($ratio < 0.2) return "#ee0000";
	if ($ratio < 0.3) return "#dd0000";
	if ($ratio < 0.4) return "#cc0000";
	if ($ratio < 0.5) return "#bb0000";
	if ($ratio < 0.6) return "#aa0000";
	if ($ratio < 0.7) return "#990000";
	if ($ratio < 0.8) return "#880000";
	if ($ratio < 0.9) return "#770000";
	if ($ratio < 1)   return "#660000";
	return "#ffae00";
}

function getagent($httpagent, $peerid)
{
	$httpagents = $peerids = $clients = array();

	$peerids[] = '/.*BC00([0-9]{2}).*/s';
	$clients[] = 'BitComet/0.\\1';

	$peerids[] = '/.*FG[0-9]+([0-9]+)([0-9]+)([0-9]+).*/s';
	$clients[] = 'FlashGet/\\1.\\2.\\3';

	$peerids[] = '/.*exbc\08.*/s';
	$clients[] = 'BitComet/0.56';

	$peerids[] = '/.*exbc\09.*/s';
	$clients[] = 'BitComet/0.57';

	$peerids[] = '/.*exbc\0:.*/s';
	$clients[] = 'BitComet/0.58';

	$peerids[] = '/.*exbc\0L.*/s';
	$clients[] = 'BitLord/1.0';

	$peerids[] = '/.*exbcL.*/s';
	$clients[] = 'BitLord/1.1';

	$peerids[] = '/.*UDP0.*/s';
	$clients[] = 'BitSpirit v.3';

	$peerids[] = '/.*ML([0-9]+).([0-9]+).([0-9]+).*/s';
	$clients[] = 'MLDonkey/\\1.\\2.\\3';

	$peerids[] = '/.*UT([0-9]+)([0-9]+)([0-9]+)([0-9A-Z]+).*/s';
	$clients[] = '&mu;Torrent/\\1.\\2.\\3.\\4';

	$peerids[] = '/.*CT([0-9]+)([0-9]+)([0-9]+)([0-9]+).*/s';
	$clients[] = 'cTorrent/\\1.\\2.\\3.\\4';

	$peerids[] = '/.*CD[0-9]+([0-9]+)[0-9]+([0-9]+).*/s';
	$clients[] = 'Enhanced CTorrent/\\1.\\2';

	$peerids[] = '/.*KT([0-9])([0-9])([0-9A-Z])([0-9A-Z]).*/s';
	$clients[] = 'KTorrent/\\1.\\2.\\3.\\4';

	$peerids[] = '/.*btpd\/([0-9]+\.[0-9]{2}).*/s';
	$clients[] = 'btpd/\\1';

	$peerids[] = '/.*M([0-9])-([0-9])-([0-9]).*/s';
	$clients[] = 'BitTorrent/\\1.\\2.\\3';

	$peerids[] = '/-G3.*/s';
	$clients[] = 'G3 Torrent';

	$peerids[] = '/.*AZ([0-9])([0-9])([0-9])([0-9]).*/s';
	$clients[] = 'Azureus/\\1.\\2.\\3.\\4';

	$peerids[] = '/.*LP([0-9])([0-9])([0-9])([0-9]).*/s';
	$clients[] = 'Lphant/\\2.\\3\\4';

	$peerids[] = '/.*DE([0-9])([0-9])([0-9])([0-9]).*/s';
	$clients[] = 'Deluge/\\1.\\2.\\3';

	$peerids[] = '/.*XX([0-9])([0-9])([0-9])([0-9]).*/s';
	$clients[] = 'Xtorrent/\\1.\\2';

	$recognised_client = preg_replace($peerids, $clients, $peerid);

	if ($recognised_client != $peerid)
	{
		return $recognised_client;
	}
	else
	{
		$clients = array();

		$httpagents[] = '/.*Bitcomet Turbo ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]).*/s';
		$clients[] = 'Bitcomet Turbo/\\1';

		$httpagents[] = '/.*BitTorrent\/S-([0-9]+\.[0-9]+\.[0-9]+).*/s';
		$clients[] = 'Shadow\'s/\\1';

		$httpagents[] = '/.*BitTorrent\/([0-9]+\.[0-9]+\.[0-9]+).*/s';
		$clients[] = 'Bittorrent/\\1';

		$httpagents[] = '/.*BitTorrent\/U-([0-9]+\.[0-9]+\.[0-9]+).*/s';
        $clients[] = 'UPnP/\\1';

        $httpagents[] = '/.*BitTor(rent|nado)\/T-(.+).*/s';
        $clients[] = 'BitTornado/\\2';

        $httpagents[] = '/.*ABC-([0-9]+\.[0-9]+\.[0-9]).*/s';
        $clients[] = 'ABC/\\1';

        $httpagents[] = '/.*Fast Torrent ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]).*/s';
        $clients[] = 'Fast Torrent/\\1';

        $httpagents[] = '/.*rtorrent\/([0-9]+\.[0-9]+\.[0-9]).*/s';
        $clients[] = 'rtorrent/\\1';

        $httpagents[] = '/.*Python-urllib\/.+?, BitTorrent\/([0-9]+\.[0-9]+\.[0-9]+).*/s';
        $clients[] = 'BitTorrent/\\1';

        $httpagents[] = '/.*DansClient.*/s';
        $clients[] = 'XanTorrent';

        $httpagents[] = '/.*BitTorrent\/brst.*/s';
        $clients[] = 'Burst/\\1';

        $httpagents[] = '/.*Shareaza ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]).*/s';
        $clients[] = 'Shareaza/\\1';

        $httpagents[] = '/.*Rufus\/([0-9]+\.[0-9]+\.[0-9]+).*/s';
        $clients[] = 'Rufus/\\1';

        $httpagents[] = '/.*eXeem ([0-9]+\.[0-9]{2}).*/s';
        $clients[] = 'eXeem \\1';

        $httpagents[] = '/.*BinTorrent ([0-9]+\.[0-9]+).*/s';
        $clients[] = 'BinTorrent \\1';

        $httpagents[] = '/.*ML(Donkey)\/([0-9]+)\.([0-9]+)(\.([0-9]+)|).*/si';
        $clients[] = 'MLDonkey/\\2.\\3.\\4';

        $httpagents[] = '/.*ed2k_plugin v([0-9]+\.[0-9]+).*/s';
        $clients[] = 'eDonkey/\\1';

        $httpagents[] = '/.*0P3R4H.*/s';
        $clients[] = 'Opera BT Client';

        $httpagents[] = '/.*Opera\/([0-9]+)\.([0-9]+).*/s';
        $clients[] = 'Opera/\\1.\\2';

        $httpagents[] = '/.*qBittorrent v([0-9]+)\.([0-9]+)\.([0-9]+)*/s';
        $clients[] = 'qBittorrent/\\1.\\2.\\3';

        $httpagents[] = '/.*Ares ([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)*/s';
        $clients[] = 'Ares/\\1.\\2.\\3.\\4';

        $httpagents[] = '/.*libtorrent(\/| )([0-9]+)\.([0-9]+)\.([0-9]+)(\.([0-9]+)|)*/s';
        $clients[] = 'libtorrent/\\2.\\3';

        $httpagents[] = '/.*Transmission\/([0-9]+)\.([0-9]+)([0-9]+|)([0-9A-Z]+|).*/s';
        $clients[] = ' Transmission/\\1.\\2 ';

        $httpagents[] = '/.*LimeWire\/([0-9]+)\.([0-9]+)\.([0-9]+).*/s';
        $clients[] = ' LimeWire/\\1.\\2.\\3 ';

        $httpagents[] = '/.*supertorrent.*/s';
        $clients[] = 'SuperTorrent';

        $httpagents[] = '/.*Halite v ([0-9]+)\.([0-9]+)\.([0-9]+).*/s';
        $clients[] = 'Halite/\\1.\\2.\\3';

        $recognised_client = preg_replace($httpagents, $clients, $httpagent);

        if ($recognised_client != $httpagent)
        {
        	return trim($recognised_client);
        }
        else
        {
        	return '---';
        }
	}
}

function mksize($bytes)
{
	if ($bytes < 1000 * 1024)
		return number_format($bytes / 1024, 2) . "kB";
	if ($bytes < 1000 * 1048576)
		return number_format($bytes / 1048576, 2) . "MB";
	if ($bytes < 1000 * 1073741824)
		return number_format($bytes / 1073741824, 2) . "GB";
	if ($bytes < 1000 * 1099511627776)
		return number_format($bytes / 1099511627776, 2) . "TB";
	if ($bytes < 1000 * 1125899906842620)
		return number_format($bytes / 1125899906842620, 2) . "PB";
	if ($bytes < 1000 * 1152921504606850000)
		return number_format($bytes / 1152921504606850000, 2) . "EB";
}
